package app

// Evapotranspiration 三层模型蒸发
type Evapotranspiration struct {
	//========模型参数========//
	KC float64 `json:"KC;comment:流域蒸散发折算系数，敏感"`
	LM float64 `json:"LM;下层张力水容量/mm，敏感，60~90"`
	C  float64 `json:"C;深层蒸散发折算系数，不敏感，0.10~0.20"`
	//========模型状态========//
	WU float64 `json:"WU"` //上层张力水蓄量，mm
	//double WU;   //上层张力水蓄量，mm
	WL float64 `json:"WL"` //下层张力水蓄量，mm
	//double WL;   //下层张力水蓄量，mm
	EP float64 `json:"EP"` //单元流域蒸发能力，mm
	//double EP;   //单元流域蒸发能力，mm
	E float64 `json:"E"` //总的蒸散发量，mm
	//double E;    //总的蒸散发量，mm
	EU float64 `json:"EU"` //上层蒸散发量，mm
	//double EU;   //上层蒸散发量，mm
	EL float64 `json:"EL"` // 下层蒸散发量，mm
	//double EL;   //下层蒸散发量，mm
	ED float64 `json:"ED"` // 深层蒸散发量，mm
	//double ED;   //深层蒸散发量，mm

	//========外部输入========//
	P  float64 `json:"P"`  //降雨量，mm
	EM float64 `json:"EM"` //水面蒸发量，mm
}

func (e *Evapotranspiration) SetParams(para *Params) {
	e.LM = para.MLM
	e.KC = para.MKC
	e.C = para.MC

	// 设置一些常用的默认值
	e.WU = 10.0
	e.WL = 30.0
}

func (e *Evapotranspiration) SetState(s *State) {
	e.P = s.P
	e.EM = s.EM
	e.WU = s.WU
	e.WL = s.WL
}

// Calculate 计算
func (e *Evapotranspiration) Calculate() {
	// 计算流域蒸发能力
	EP := e.KC * e.EM

	e.EU = 0
	e.EL = 0
	e.ED = 0

	// 先考虑用上层提供蒸发
	if e.P+e.WU >= EP {
		// 能完全提供流域蒸发，使用上层张力蓄水量提供
		e.EU = EP
	} else {
		// 上层不能完全提供，下层通过毛细管等补充
		e.EU = e.P + e.WU
		remaining := EP - e.WU // 还需要蒸发的水量
		//  e.WL >= e.C*e.LM 中层水达到一定的湿润比例
		if e.WL >= e.C*e.LM {
			// 如果下层含水量大于下层蒸发能力，则从蒸发能力中扣除
			e.EL = remaining * (e.WL / e.LM)
		} else {
			if e.WL >= e.C*remaining {
				e.EL = e.C * remaining
			} else {
				e.EL = e.WL
				e.ED = e.C*remaining - e.EL
			}
		}
	}
	e.EP = EP
	e.E = e.EL + e.EU + e.ED
}

func (e *Evapotranspiration) UpdateState(s *State) {
	s.EP = e.EP
	s.E = e.E
	s.EU = e.EU
	s.EL = e.EL
	s.ED = e.ED
}
